import Vue from "vue";
import Axios from "axios";
import qs from "qs";

let sessionTicket = "";

let getSessionTicketUrl = "/Basic/createSessionTicket";

let gettingSessionTicket = false;

let getSessionTicketTimes = 0;

// Axios.defaults['withCredentials'] = true;

let axios = Axios.create({
    baseURL: process.env.NODE_ENV == 'development' ? 'http://student-api-dev.wxhand.com/customer_service' : 'https://student-api.zsdx.cn/customer_service',
    transformRequest: [
        function(data, headers) {
            var resData = data;

            if (!(resData instanceof FormData)) {
                resData = qs.stringify(resData);
            }
            return resData;
        },
    ],
    // headers: {},
    method: "post",
});

axios.interceptors.request.use(
    function(config) {
        // 这里的config包含每次请求的内容
        // 上传文件到又拍云不允许加header
        if (config.url.indexOf("api.upyun.com") < 0) {
            config.headers["zsdx-session-ticket"] = sessionTicket;
        }
        return config;
    },
    function(err) {
        return Promise.reject(err);
    }
);

function getSessionTicketLocal() {
    if (!sessionTicket) {
        sessionTicket = localStorage.sessionTicket;
    }

    return sessionTicket;
}

/** 向服务器索取新的sessionTicket */
function getSessionTicketRemote(callback) {
    if (getSessionTicketTimes > 10) {
        Vue.prototype.$notify.error({
            title: "错误",
            message: "服务器错误，请稍后重试",
        });
        return;
    }
    gettingSessionTicket = true;
    axios
        .post(getSessionTicketUrl, {})
        .then(function(response) {
            if (response.status != "200") {
                return Promise.reject(res);
            }
            let resp = response.data;

            if (resp.code == 1) {
                // 重置请求次数
                getSessionTicketTimes = 0;
                sessionTicket = resp.data.session_ticket;
                // 本地存储
                localStorage.sessionTicket = sessionTicket;
            }
            gettingSessionTicket = false;
            getSessionTicketTimes++;
            if (callback) {
                callback(sessionTicket);
            }
        })
        .catch(function(err) {
            gettingSessionTicket = false;
            getSessionTicketTimes++;
            return Promise.reject(err);
        });
}

/** 获取sessiongTicket */
function getSessionTicket(callback) {
    let st = "";

    if (gettingSessionTicket) {
        setTimeout(function() {
            callback("");
        }, 200);
        return;
    }
    st = getSessionTicketLocal();
    if (st) {
        callback(st);
    } else {
        getSessionTicketRemote(function(st) {
            callback(st);
        });
    }
}
/**
 * 处理请求返回结果
 * @param resp axios返回原始数据,
 * @param instance 调用接口原始vue实例
 */
function dealResponse(resp, options) {
    if (resp.status != "200") {
        return Promise.reject(res);
    }

    let instance = options.instance;

    // sessionTicket缺失或者失效
    if (resp.data.code == 1001) {
        if (gettingSessionTicket) {
            setTimeout(function() {
                instance.$post(
                    options.url,
                    options.data,
                    options.success,
                    options.fail
                );
            }, 200);
            return;
        }
        getSessionTicketRemote(function(currTicket) {
            instance.$post(
                options.url,
                options.data,
                options.success,
                options.fail,
                currTicket
            );
        });
        return;
    }

    // 未登录
    if (resp.data.code == 1002) {
        instance.$router.push({
            name: "Login",
            params: {
                dist: {
                    path: instance.$route.path,
                    query: instance.$route.query,
                },
            },
        });
        return;
    }

    // 其它地方登录
    if (resp.data.code == 1003) {
        instance.$router.replace({
            path: "/Login?target=quit",
        });
        return;
    }

    //密码已修改
    if (resp.data.code == 1004) {
        instance.$router.replace({
            path: "/Login?target=change",
        });
        return;
    }

    if (options.success) {
        options.success(resp.data);
    }
}

/** 清除客户端保留sessionTicket */
function clearSessionTicket() {
    if (sessionTicket == localStorage.sessionTicket) {
        localStorage.sessionTicket = undefined;
    }
    sessionTicket = undefined;
}
/** 手动设置sessionTicket */
function setSessionTicket(ticket) {
    sessionTicket = ticket;
    // 本地存储 防止出现覆盖管理员身份,只是保存临时变量,刷新丢失
    localStorage.sessionTicket = ticket;
}

/**
 * 一般post请求
 * @param
 */
function post(url, data, success, fail, session_ticket) {
    let instance = this;

    let st = session_ticket;

    if (!st && url != getSessionTicketUrl) {
        getSessionTicket(function(currTicket) {
            instance.$post(url, data, success, fail, currTicket);
        });
    } else {
        axios
            .post(url, data)
            .then(function(resp) {
                dealResponse(resp, {
                    instance,
                    url,
                    data,
                    success,
                    fail,
                });
            })
            .catch(function(err) {
                if (fail) {
                    fail(err);
                }
                return Promise.reject(err);
            });
    }
}

/**
 * 上传文件请求
 * @param options 请求相关配置{url, data, progress(上传进度), success, fail}
 * @param session_ticket ticket
 */
function upload(options, session_ticket) {
    let instance = this;

    let st = session_ticket;

    if (!st && options.url != getSessionTicketUrl) {
        getSessionTicket(function(currTicket) {
            instance.$upload(options, currTicket);
        });
    } else {
        axios
            .post(options.url, options.data, {
                onUploadProgress: function(e) {
                    if (e.total > 0) {
                        e.percent = (e.loaded / e.total) * 100;
                    }
                    if (options.progress) {
                        options.progress(e);
                    }
                },
            })
            .then(function(resp) {
                dealResponse(resp, {
                    instance,
                    url: options.url,
                    data: options.data,
                    success: options.success,
                    fail: options.success,
                });
            })
            .catch(function(err) {
                if (options.fail) {
                    options.fail(err);
                }
                return Promise.reject(err);
            });
    }
}

function install(Vue, options) {
    Vue.axios = Axios;

    Object.defineProperties(Vue.prototype, {
        $post: {
            get() {
                return post.bind(this);
            },
        },
        $upload: {
            get() {
                return upload.bind(this);
            },
        },
        axios: {
            get() {
                return axios;
            },
        },
        clearSessionTicket: {
            get() {
                return clearSessionTicket;
            },
        },
        setSessionTicket: {
            get() {
                return setSessionTicket;
            },
        },
    });
}

export default {
    install,
};
